#include "burnint.h"

BurnSyncThread *pBurnDrvDrawThread = NULL;

static void ThreadFunc(void *pArg)
{
    BurnSyncThread *pThread = (BurnSyncThread *)pArg;

    while (!pThread->bStop)
    {
        BurnLockLock(pThread->Lock);
        while (pThread->bWait)
            BurnCondWait(pThread->Cond, pThread->Lock);
        pThread->bWait = true;

        pThread->Func();

        BurnLockUnlock(pThread->Lock);
    }
}

INT32 BurnSyncThreadLock(BurnSyncThread *pThread)
{
    return BurnLockLock(pThread->Lock);
}

INT32 BurnSyncThreadUnlock(BurnSyncThread *pThread)
{
    return BurnLockUnlock(pThread->Lock);
}

INT32 BurnSyncThreadSignal(BurnSyncThread *pThread)
{
    pThread->bWait = false;
    return BurnCondSignal(pThread->Cond);
}

INT32 BurnSyncThreadCreate(BurnSyncThread **pThread, void (*Func)())
{
    BurnSyncThread *Thread = (BurnSyncThread *)malloc(sizeof(BurnSyncThread));
    if (!Thread)
        goto FAILED;
    memset(Thread, 0, sizeof(*Thread));

    Thread->Func = Func;
    Thread->bStop = false;
    Thread->bWait = true;

    if (BurnLockCreate(&Thread->Lock) != 0)
        goto FAILED;

    if (BurnCondCreate(&Thread->Cond) != 0)
        goto FAILED;

    if (BurnThreadCreate(&Thread->Thd, ThreadFunc, Thread) != 0)
        goto FAILED;

    *pThread = Thread;
    return 0;

FAILED:
    if (Thread)
    {
        BurnThreadDestroy(Thread->Thd);
        BurnLockDestroy(Thread->Lock);
        BurnCondDestroy(Thread->Cond);
        free(Thread);
    }
    return 1;
}

INT32 BurnSyncThreadDestroy(BurnSyncThread *pThread)
{
    if (!pThread)
        return 1;

    BurnLockLock(pThread->Lock);
    pThread->bStop = true;
    pThread->bWait = false;
    BurnCondSignal(pThread->Cond);
    BurnLockUnlock(pThread->Lock);

    BurnThreadDestroy(pThread->Thd);
    BurnLockDestroy(pThread->Lock);
    BurnCondDestroy(pThread->Cond);

    free(pThread);

    return 0;
}
